#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

class AudioPalyer;
class State
{
protected:
    AudioPalyer* player = nullptr;
public:
    State(AudioPalyer *player_):player(player_)
    {
    }
    virtual void clickLock() = 0;
    virtual void clickPlay() = 0;
    virtual void clickNext() = 0;
    virtual void clickPrevious() = 0;
};
class ReadyState;
class AudioPalyer
{
private:
    State* state;
public:
    AudioPalyer();
    void clickLock()
    {
        state->clickLock();
    }
    void clickPlay()
    {
        state->clickPlay();
    }
    void clickNext()
    {
        state->clickNext();
    }
    void clickPrevious()
    {
        state->clickPrevious();
    }
    void changeState(State* nextstate)
    {
        state = nextstate;
    }

    void playSong()
    {
        std::cout<<"Play Song"<<std::endl;
    }
    void nextSong()
    {
        std::cout<<"Next Song"<<std::endl;
    }
    void previousSong()
    {
        std::cout<<"Previous Song"<<std::endl;
    }
};

class PlayingState : public State{
public:
    PlayingState(AudioPalyer *player_):State(player_){}
    void clickLock() override;

    void clickPlay() override
    {
        player->playSong();
    }
    void clickNext() override
    {
    }
    void clickPrevious() override
    {
    }
};
class LockedState : public State{
public:
    LockedState(AudioPalyer *player_):State(player_){}
    void clickLock() override
    {
    }
    void clickPlay() override;
    void clickNext() override
    {
    }
    void clickPrevious() override
    {
    }
};
class ReadyState : public State{
public:
    ReadyState(AudioPalyer *player_):State(player_){}
    void clickLock() override
    {
        player->changeState(new LockedState(player));
    }
    void clickPlay() override
    {
        player->changeState(new PlayingState(player));
    }
    void clickNext() override
    {
        player->nextSong();
    }
    void clickPrevious() override
    {
        player->previousSong();
    }
};
AudioPalyer::AudioPalyer()
{
    state = new ReadyState(this);
}
void PlayingState::clickLock()
{
    player->changeState(new ReadyState(player));
}
void LockedState::clickPlay()
{
    player->changeState(new ReadyState(player));
}
//                 ------clickPlay--------->
//        READY(nextSong,previousSong)      PLAY(playSong)
//      |       ↑ <------clickLock---------
//      |       |
//clickLock clickPlay
//      |       |
//      ↓       |
//        LOCK
int main() {
    AudioPalyer player; //READY
    player.clickLock(); // --> LOCK
    player.clickNext();  // no response
    player.clickPlay(); // --> READY
    player.clickNext();  // next song
    player.clickPlay(); // --> PLAY
    player.clickPlay(); // play song
    player.clickNext();  // no response
    return 0;
}



